package com.example.design.函数式编程.d简单流;

import java.util.*;
import java.util.function.*;

/**
 * 模仿学习过的stream,实现自己的流，提供基本的高阶函数如map,filter,foreach
 */
public class SimpleStream<T> {

    private Collection<T> collection;

    private SimpleStream(Collection<T> collection) {
        this.collection = collection;
    }

    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);

        SimpleStream.of(list)
                .filter(item -> (item & 1) == 1)
                .map(item -> item * item)
                .forEach(System.out::println);

        Integer sum = SimpleStream.of(list).reduce(0, Integer::sum);
        System.out.println(sum);

        Integer min = SimpleStream.of(list).reduce(Integer.MAX_VALUE, Integer::min);
        System.out.println(min);

        Integer max = SimpleStream.of(list).reduce(Integer.MIN_VALUE, Integer::max);
        System.out.println(max);

        Set<Integer> collect = SimpleStream.of(list).collect(HashSet::new, (set, t) -> set.add(t));
        System.out.println(collect);

        StringBuffer collect1 = SimpleStream.of(list).collect(StringBuffer::new, StringBuffer::append);
        System.out.println(collect1);

        StringJoiner collect2 = SimpleStream.of(list).map(item -> String.valueOf(item)).collect(() -> new StringJoiner("-"), StringJoiner::add);
        System.out.println(collect2);

    }

    /**
     * 收集
     */
    public <C> C collect(Supplier<C> supplier, BiConsumer<C, T> consumer) {
        // 创建容器
        C c = supplier.get();
        // 向容器中添加元素
        for (T t : collection) {
            consumer.accept(c, t);
        }
        return c;
    }

    /**
     * 化简
     * T代表初始值
     */
    public T reduce(T o, BinaryOperator<T> operator) {
        T p = o;
        for (T t : collection) {
            p = operator.apply(p, t);
        }
        return p;
    }

    /**
     * 遍历
     *
     * @param consumer
     */
    public void forEach(Consumer<T> consumer) {
        for (T t : collection) {
            consumer.accept(t);
        }
    }

    /**
     * 映射
     *
     * @param predicate
     * @param <U>
     * @return
     */
    public <U> SimpleStream<U> map(Function<T, U> predicate) {
        List<U> result = new ArrayList<>();
        for (T t : collection) {
            U apply = predicate.apply(t);
            result.add(apply);
        }
        return new SimpleStream<>(result);
    }

    /**
     * 过滤
     *
     * @param predicate
     * @return
     */
    public SimpleStream<T> filter(Predicate<T> predicate) {
        List<T> result = new ArrayList<>();
        for (T t : collection) {
            if (predicate.test(t)) {
                result.add(t);
            }
        }
        return new SimpleStream<>(result);
    }


    /**
     * @param collection 支持list,set等
     * @param <T>
     * @return
     */
    public static <T> SimpleStream<T> of(Collection<T> collection) {
        return new SimpleStream<>(collection);
    }
}
